//
// Created by work on 24-5-30.
//

#include "iot_model_device/device_model_mgr/CUserMgr.h"
#include "iot_model_device/device_model_mgr/CSsqlMgr.h"
#include "jwt-cpp/base.h"
#include "jwt-cpp/jwt.h"
#include <chrono>
#include <ctime>

namespace iotplat {

    Json::Value CUserMgr::userRegister(Json::Value &jsonuser) {
        std::string userName = jsonuser[userFieldName(USER_ENUM::EUserId)].asString();
        if(!CSsqlMgr::checkUserNoExist(userName)) {
            return errorJson("用户名已经存在");
        }

        if(!CSsqlMgr::addUser(jsonuser)) {
            return errorJson("注册失败!");
        }

        if(!CRedisDbMgr::loadUser(userName)) {
            return errorJson("注册失败!");
        }

        Json::Value succResJson = successJson("注册成功");
        CSsqlMgr::getUser(userName, succResJson);
        return succResJson;
    }

    Json::Value CUserMgr::userLogin(Json::Value &jsonuser) {
        std::string userid = jsonuser[userFieldName(USER_ENUM::EUserId)].asString();
        std::string pwd = jsonuser[userFieldName(USER_ENUM::EPwd)].asString();
        if(!CRedisDbMgr::checkUserExist(userid))
            return errorJson("用户不存在，请检查后重试!");

        CUserInfo user;
        if(!CRedisDbMgr::getRtUser(userid, user)){
            return errorJson("读取用户信息失败!");
        }

        if(pwd != user.pwd) {
            return errorJson("密码错误，请检查!");
        }

        std::string token = createToken();
        Json::Value resvalue = user.toJson();
        resvalue["token"] = token;

        return resvalue;
    }

    std::string CUserMgr::createToken() {
        auto token = jwt::create()
                .set_type("JWS")
                .set_issuer("iotplat_void")
                .set_payload_claim("sample", jwt::claim(std::string("iot_plat")))
                .set_issued_at(std::chrono::system_clock::now()) // 添加令牌签发时间
                .set_expires_at(std::chrono::system_clock::now() + std::chrono::seconds(3600)) // 添加令牌过期时间（1小时）
                .sign(jwt::algorithm::hs256{"secret"});
        return token;
    }

    bool CUserMgr::checkToken(const std::string &token)
    {
        try
        {
            auto decoded_token = jwt::decode(token);
            auto verifier = jwt::verify()
                    .with_issuer("iotplat_void")
                    .with_claim("sample", jwt::claim(std::string("iot_plat")))
                    .allow_algorithm(jwt::algorithm::hs256{"secret"});

            verifier.verify(decoded_token);

            return true;
        }
        catch (const std::exception& e)
        {
            // Token验证失败，可以记录日志或者其他处理
            return false;
        }
    }
} // iotplat